{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# How to await callbacks in serverless environments\n",
        "\n",
        ":::info Prerequisites\n",
        "\n",
        "This guide assumes familiarity with the following concepts:\n",
        "\n",
        "- [Callbacks](/docs/concepts/callbacks)\n",
        "\n",
        ":::\n",
        "\n",
        "As of `@langchain/core@0.3.0`, LangChain.js callbacks run in the background. This means that execution will **not** wait for the callback to either return before continuing. Prior to `0.3.0`, this behavior was the opposite.\n",
        "\n",
        "If you are running code in [serverless environments](https://en.wikipedia.org/wiki/Serverless_computing) such as [AWS Lambda](https://aws.amazon.com/pm/lambda/) or [Cloudflare Workers](https://workers.cloudflare.com/) you should set your callbacks to be blocking to allow them time to finish or timeout.\n",
        "\n",
        "To make callbacks blocking, set the `LANGCHAIN_CALLBACKS_BACKGROUND` environment variable to `\"false\"`. Alternatively, you can import the global [`awaitAllCallbacks`](https://api.js.langchain.com/functions/langchain_core.callbacks_promises.awaitAllCallbacks.html) method to ensure all callbacks finish if necessary.\n",
        "\n",
        "To illustrate this, we'll create a [custom callback handler](/docs/how_to/custom_callbacks) that takes some time to resolve, and show the timing with and without `LANGCHAIN_CALLBACKS_BACKGROUND` set to `\"false\"`. Here it is without the variable set along with the `awaitAllCallbacks` global:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Elapsed time: 1ms\n",
            "Call finished\n",
            "Final elapsed time: 2164ms\n"
          ]
        }
      ],
      "source": [
        "import { RunnableLambda } from \"@langchain/core/runnables\";\n",
        "import { awaitAllCallbacks } from \"@langchain/core/callbacks/promises\";\n",
        "\n",
        "const runnable = RunnableLambda.from(() => \"hello!\");\n",
        "\n",
        "const customHandler = {\n",
        "  handleChainEnd: async () => {\n",
        "    await new Promise((resolve) => setTimeout(resolve, 2000));\n",
        "    console.log(\"Call finished\");\n",
        "  },\n",
        "};\n",
        "\n",
        "const startTime = new Date().getTime();\n",
        "\n",
        "await runnable.invoke({ number: \"2\" }, { callbacks: [customHandler] });\n",
        "\n",
        "console.log(`Elapsed time: ${new Date().getTime() - startTime}ms`);\n",
        "\n",
        "await awaitAllCallbacks();\n",
        "\n",
        "console.log(`Final elapsed time: ${new Date().getTime() - startTime}ms`);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can see that the initial `runnable.invoke()` call finishes in a short amount of time, and then roughly two seconds later, the callbacks finish.\n",
        "\n",
        "And here it is with backgrounding off:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Call finished\n",
            "Initial elapsed time: 2002ms\n"
          ]
        }
      ],
      "source": [
        "process.env.LANGCHAIN_CALLBACKS_BACKGROUND = \"false\";\n",
        "\n",
        "const startTimeBlocking = new Date().getTime();\n",
        "\n",
        "await runnable.invoke({ number: \"2\" }, { callbacks: [customHandler] });\n",
        "\n",
        "console.log(`Initial elapsed time: ${new Date().getTime() - startTimeBlocking}ms`);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This time, the initial call by itself takes two seconds because the `invoke()` call waits for the callback to return before returning.\n",
        "\n",
        "## Next steps\n",
        "\n",
        "You've now learned how to run callbacks in the background to reduce latency.\n",
        "\n",
        "Next, check out the other how-to guides in this section, such as [how to create custom callback handlers](/docs/how_to/custom_callbacks)."
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "TypeScript",
      "language": "typescript",
      "name": "tslab"
    },
    "language_info": {
      "codemirror_mode": {
        "mode": "typescript",
        "name": "javascript",
        "typescript": true
      },
      "file_extension": ".ts",
      "mimetype": "text/typescript",
      "name": "typescript",
      "version": "3.7.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}